/** 可选参数 */
// 不对外直接提供调用，全小写命名。
class optional {
    constructor(public types: Array<string>) { }
    get [Symbol.toStringTag]() { return optional.name; };
}

interface _CF_ {
    /** 常用参数类型 */
    argType: {
        /** 可选项 */
        optional: (...types: Array<Ttypeof>) => optional,

        /** 任意类型且可选 */
        optionalAny: optional,
        /** 值类型且可选 对应类型 @see Tvalue */
        optionalValue: optional,

        /** 原始类型 对应类型 @see Tprimitive */
        primitive: Array<string>,
        /** 键类型 对应类型 @see PropertyKey */
        propertyKey: Array<string>,
        /** 值类型 对应类型 @see Tvalue */
        value: Array<string>,
        /** 嵌套类型 */
        nest: Array<string>,

        /** 无参类型 */
        noArgs: string,
        /** 任意类型 */
        any: string,
        /** 剩余参数类型 */
        rest: string,
    },
}
{
    const argType = {
        optional: (...types: Array<Ttypeof>) => { return new optional(types); },
        noArgs: '',
        any: '*',
        rest: '...',
    };
    Object.defineProperty(argType, 'primitive', {
        get() { return [Etype.undefined, Etype.null, Etype.string, Etype.boolean, Etype.number, Etype.symbol, Etype.bigint]; },
    });
    Object.defineProperty(argType, 'optionalAny', {
        get() { return new optional(['*']); },
    });
    Object.defineProperty(argType, 'optionalValue', {
        get() { return new optional([Etype.undefined, Etype.null, Etype.string, Etype.boolean, Etype.number]); },
    });
    Object.defineProperty(argType, 'propertyKey', {
        get() { return [Etype.string, Etype.number, Etype.symbol]; },
    });
    Object.defineProperty(argType, 'value', {
        get() { return [Etype.undefined, Etype.null, Etype.string, Etype.boolean, Etype.number]; },
    });
    Object.defineProperty(argType, 'nest', {
        get() { return [Etype.array, Etype.obj, Etype.Map, Etype.Set]; },
    });

    Object.defineProperty(_CF_.prototype, 'argType', {
        writable: false,
        configurable: false,
        enumerable: false,
        value: argType
    });
}
